using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Xml.Schema;
using DeclarativeTest.Core.Support;
using Mistral.Utils;
using Mistral.Xml;

namespace DeclarativeTest.Core
{
	public class TestManager
	{
		public ITestRunner Runner{ get; set; }
		public ITestSuiteFactory Factory{ get; set; }
		public ITestSuiteParser Parser{ get; set; }

		private static TestManager __current;
		
		public static TestManager Current
		{
			[DebuggerStepThrough]
			get
			{
				if( __current == null )
				{
					TestManager testManager = new TestManager();
					
					testManager.Runner = new TestRunner();
					testManager.Factory = new TestFactory();
					testManager.Parser = new TestSuiteParser();

					__current = testManager;
				}
				return __current;
			}
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="T:System.Object"/> class.
		/// </summary>
		TestManager( )
		{
			ProcessActionProvidersFromAssemblies();
		}

		private static void ProcessActionProvidersFromAssemblies( )
		{
			IEnumerable<Type> actionProviderTypes = ReflectionUtils.GetAvailableTypesForCurrentDomain(
				type => type.Implements<IActionProvider>() );

			foreach ( Type actionProviderType in actionProviderTypes )
			{
				IActionProvider actionProvider = (IActionProvider) Activator.CreateInstance( actionProviderType );
				
				// Register schemas
				XmlSchemas schemas = new XmlSchemas( actionProvider.GetSchemaLocations() );
				SchemaRegistry.Register( schemas.SchemaSet );

				// Register action factory
				ActionRegistry.RegisterFactory( actionProvider.GetActionFactory() );
			}
		}

		public static ITestSuite CreateFromFile( string fileName )
		{
			TestSuiteInfo testSuiteInfo = Current.Parser.ParseFromFile( fileName );
			return Current.Factory.CreateTestSuite( testSuiteInfo );
		}
	}
}